home *** CD-ROM | disk | FTP | other *** search
- #include<stdio.h>
- #include<stdlib.h>
- #include<conio.h>
- #include<fcntl.h>
- #include<io.h>
- #include<vsa.h>
- #include<vsa_font.h>
- #include<tiff.h>
-
- #ifndef _MSC_VER
- /*..... This is line for Borland C Only ! .....*/
- extern unsigned _stklen = 13000;
- #endif
-
- void draw_dithered_pixel(int,int,unsigned char *,int);
- int crack_rgb(unsigned char *,int *,int *,int *,float *,
- float *,float *);
- unsigned long read_tga_header(int,int *,int *,int *,int *);
- void true_color_lut(void);
- void vsa_get_input(char *);
- void update_message(int,int,int,char *);
- void clear_text_area(int,int,int,int);
- void color_bar(int,int);
-
- unsigned char dither[4][64]={
- {
- 1 },
- {
- 1, 3,
- 4, 2 },
- {
- 1, 9, 3, 11,
- 13, 5, 15, 7,
- 4, 12, 2, 10,
- 16, 8, 14, 6 },
- {
- 1, 33, 9, 41, 3, 35, 11, 43,
- 49, 17, 57, 25, 51, 19, 59, 27,
- 13, 45, 5, 37, 15, 47, 7, 39,
- 61, 29, 53, 21, 63, 31, 55, 23,
- 4, 36, 12, 44, 2, 34, 10, 42,
- 52, 20, 60, 28, 50, 18, 58, 26,
- 16, 48, 8, 40, 14, 46, 6, 38,
- 64, 32, 56, 24, 62, 30, 54, 22 },
- };
-
- /*......................... DITHER.C............. 5-29-94 .....*/
- /* This program reads True Color (24 bit per pixel) TARGA */
- /* images and converts them to 8 bit dithered screen images. */
- /* It also writes out the dithered image as an 8 bit per pixel */
- /* Palette Color TIFF image. */
- /*.............................................................*/
- void main(int argc, char *argv[])
- {
- char filename[80],text[100];
- int i,j,size,width,height,type,file_handle,orient,vmode;
- int r0,c0;
- unsigned char rgb[3072];
- if(argc > 1)
- /*.............................................................*/
- /* If specified, set requested video mode. */
- /*.............................................................*/
- {
- sscanf(argv[1],"%x",&vmode);
- if(vsa_init(vmode) != 0)
- {
- printf("Can't set Requested VESA video mode!\n");
- printf("Is VESA BIOS Extension TSR loaded?\n");
- return;
- }
- }
- else
- /*.............................................................*/
- /* Otherwise set highest video resolution available. */
- /*.............................................................*/
- {
- if(vsa_init(0x105) != 0) /* 1024 x 768 x 256 */
- if(vsa_init(0x103) != 0) /* 800 x 600 x 256 */
- if(vsa_init(0x101) != 0) /* 640 x 480 x 256 */
- if(vsa_init(0x100) != 0) /* 640 x 400 x 256 */
- {
- printf("Can't set VESA video mode!\n");
- printf("Is VESA BIOS Extension TSR loaded?\n");
- return;
- }
- }
- /*.............................................................*/
- /* Set up the Palette as an 8 bit RGB (3,3,2) table. */
- /* and draw color look up table. */
- /*.............................................................*/
- true_color_lut();
- tf_set_prime_colors();
- color_bar(0.125*XResolution,0.91*YResolution);
- /*..........................................................................*/
- /* Draw Frame around screen. */
- /*..........................................................................*/
- vsa_set_color(TF_Blue);
- vsa_move_to(0,0);
- vsa_rect(XResolution-1,YResolution-1);
- /*..........................................................................*/
- /* Set up text cursor mode and location. */
- /*..........................................................................*/
- vsa_set_text_cursor_mode(1);
- r0 = 0.85*YCharResolution;
- c0 = 0.5*XCharResolution - 17;
- /*..........................................................................*/
- /* Enter main loop which displays dithered images. */
- /*..........................................................................*/
- LOOP:
- update_message(c0*XCharSize,r0*YCharSize,TF_Green,"Input TARGA Image Filename: ");
- vsa_get_input(filename);
- if(filename[0] == 0)
- goto BAIL;
- /*.............................................................*/
- /* Get dither size and limit it to legal value of 1,2,4 or 8. */
- /*.............................................................*/
- update_message(c0*XCharSize,(r0+1)*YCharSize,TF_Green,"Input Dither Size (1, 2, 4, or 8): ");
- vsa_get_input(text);
- sscanf(text,"%d",&size);
- if(size == 3) size = 4; /* size limited to 1, 2, 4, or 8 */
- if(size > 4) size = 8; /* size limited to 1, 2, 4, or 8 */
- /*.............................................................*/
- /* Open the TARGA file and get header info. */
- /*.............................................................*/
- if((file_handle = open(filename,O_BINARY | O_RDONLY)) == -1)
- {
- sprintf(text,"Can't find file %s",filename);
- update_message(c0*XCharSize,r0*YCharSize,TF_Red,text);
- update_message(c0*XCharSize,(r0+1)*YCharSize,TF_Red,"");
- getch();
- goto LOOP;
- }
- update_message(c0*XCharSize,r0*YCharSize,TF_Violet,"Generating Dithered Image.");
- update_message(c0*XCharSize,(r0+1)*YCharSize,TF_Red,"");
- read_tga_header(file_handle,&width,&height,&type,&orient);
- /*.............................................................*/
- /* Draw Frame around the new picture. */
- /*.............................................................*/
- vsa_set_color(TF_White);
- vsa_move_to(2,2);
- vsa_rect(width+3,height+3);
- /*.............................................................*/
- /* Read out pixels from TARGA file and plot on screen in */
- /* top down or bottom up order depending on orientation. */
- /*.............................................................*/
- if(orient == 32)
- for(j=0;j<height;j++)
- {
- read(file_handle,rgb,3*width);
- for(i=0;i<width;i++)
- draw_dithered_pixel(i+3,j+3,rgb+3*i,size);
- }
- else
- for(j=height-1;j>=0;j--)
- {
- read(file_handle,rgb,3*width);
- for(i=0;i<width;i++)
- draw_dithered_pixel(i+3,j+3,rgb+3*i,size);
- }
- color_bar(0.125*XResolution,0.91*YResolution);
- /*.............................................................*/
- /* Close the image file and look for an ESC key to quit. */
- /* Otherwise, save dithered image as an 8 bit TIFF called */
- /* NEW.TIF and LOOP for experimentation with a different */
- /* dither box size. */
- /*.............................................................*/
- close(file_handle);
- update_message(c0*XCharSize,r0*YCharSize,TF_Red,
- "ESC to quit, any other key to continue.");
- update_message(c0*XCharSize,(r0+1)*YCharSize,TF_Yellow,"");
- if(getch() == 27)
- goto BAIL;
- update_message(c0*XCharSize,r0*YCharSize,TF_Blue,
- "Saving image as NEW.TIF.");
- tf_save_file(0,0,width-1,height-1,"new.tif");
- goto LOOP; /*..... Oh No, a goto! .....*/
- BAIL:
- vsa_about();
- getch();
- vsa_set_svga_mode(0x3);
- return; /*..... End main .....*/
- }
-
- /*.................... DRAW_DITHERED_PIXEL ....... 5-27-94 ....*/
- /* This routine draws a dithered pixel at screen coordinate */
- /* 'i,j' with 24 bit color equivalent passed in the 3 byte */
- /* array 'rgb'. The dither pattern size is specified by 'size'*/
- /* and can be 1, 2, 4, or 8. Note that the global 'dither' */
- /* array must must be initialized before calling this routine. */
- /*.............................................................*/
- void draw_dithered_pixel(int i,int j,unsigned char *rgb,int size)
- {
- int n,m,q,r,red_lvl,grn_lvl,blu_lvl;
- int color,red_boost,grn_boost,blu_boost;
- float x,y,frl,fgl,fbl;
- /*.............................................................*/
- /* For the pixels screen address i,j, compute pixel address r */
- /* within the dither box. Also select dither box q based on */
- /* size (size = 1, 2, 4, or 8). */
- /*.............................................................*/
- x = (float)i/size;
- y = (float)j/size;
- m = (int)(size*(x - (int)x) + 0.5);
- n = (int)(size*(y - (int)y) + 0.5);
- q = size/2;
- if(size == 8) q = 3;
- r = m+n*size;
- /*.............................................................*/
- /* Get the Dark Pixel color, the Light Pixel components, and */
- /* the pixel color errors. */
- /*.............................................................*/
- color = crack_rgb(rgb,&red_boost,&grn_boost,&blu_boost,
- &frl,&fgl,&fbl);
- /*.............................................................*/
- /*Scale the pixel color error values based on dither box size */
- /*.............................................................*/
- red_lvl = size*size*frl;
- grn_lvl = size*size*fgl;
- blu_lvl = size*size*fbl;
- /*.............................................................*/
- /*Test the pixels red, green, and blue error values against the*/
- /*thresholds in the dither box. Decide which color to use. */
- /*.............................................................*/
- if(dither[q][r] <= red_lvl)
- color = (color & 0x1f) + (red_boost << 5); /* Boost Red */
- if(dither[q][r] <= grn_lvl)
- color = (color & 0xe3) + (grn_boost << 2); /* Boost Grn */
- if(dither[q][r] <= blu_lvl)
- color = (color & 0xfc) + blu_boost; /* Boost Blu */
- /*.............................................................*/
- /* Set color and draw pixel on screen. */
- /*.............................................................*/
- vsa_set_color(color);
- vsa_set_pixel(i,j);
- return;
- } /*.... END draw_dithered_pixel ....*/
-
-
- /*.......................... CRACK_RGB ........... 5-27-94 ....*/
- /* This routine takes the 24 bit RGB color value in the 'rgb' */
- /* array, quantizes it down to an 8 bit color value (3 bit red,*/
- /* 3 bit green, and 2 bit blue) and returns this 8 bit */
- /* 'base_color' value. It also computes the 8 bit color boost */
- /* values '*red_boost', 'grn_boost', and 'blu_boost' which are */
- /* used to draw dithered pixels. It also computes the color */
- /* error values 'red_lvl', 'grn_lvl', and 'blu_lvl' which */
- /* determine when the dither function draws with 'base_color' */
- /* and when it draws with 'xxx_boost' color. */
- /*.............................................................*/
- int crack_rgb(unsigned char *rgb,int *red_boost,int *grn_boost,
- int *blu_boost,float *red_lvl,float *grn_lvl,
- float *blu_lvl)
- {
- int base_color,red,grn,blu;
- float fred,fgrn,fblu;
-
- fred = rgb[2]/36.6; /*36.6 = (256 shades of red)/(2^3 - 1) */
- fgrn = rgb[1]/36.6; /*36.6 = (256 shades of grn)/(2^3 - 1) */
- fblu = rgb[0]/85.4; /*85.4 = (256 shades of blu)/(2^2 - 1) */
-
- red = fred;
- grn = fgrn;
- blu = fblu;
- base_color = (red << 5)+(grn << 2)+blu; /*Dark Pixel color */
-
- *red_lvl = fred - red;
- *grn_lvl = fgrn - grn;
- *blu_lvl = fblu - blu;
-
- *red_boost = red+1; /*This is the Light Pixel color for red */
- *grn_boost = grn+1; /*This is the Light Pixel color for grn */
- *blu_boost = blu+1; /*This is the Light Pixel color for blu */
-
- return base_color;
- } /*.... END crack_rgb .....*/
-
-
- /*....................... READ_TGA_HEADER ....... 5-17-94 ....*/
- /* This routine parses through a TGA header and returns the */
- /* file offset in bytes to the first byte of pixel data. */
- /* It also returns image width, height, and type (type 2 is the*/
- /* uncompressed 24 bit image type). */
- /*.............................................................*/
- unsigned long read_tga_header(int handle, int *width,
- int *height, int *type,
- int *orientation)
- {
- unsigned long offset;
- unsigned char buff[18];
- read(handle,buff,18);
- offset = 18+buff[0];
- *type = buff[2];
-
- *width = *((unsigned *)buff + 6);
- *height = *((unsigned *)buff + 7);
- *orientation = buff[17];
- return offset;
- } /*.... END read_tga_header .....*/
-
- /*.................... TRUE_COLOR_LUT.C .......... 5-15-94 ....*/
- /* This routine generates a 'true color' LUT. An 8 bit index */
- /* into the LUT represents 3 bits of RED, 3 bits of GREEN, and */
- /* 2 bits of BLUE. The 3 msbs of the 8 bit index are the RED */
- /* field, next 3 are GREEN, and the 2 lsbs are the BLUE field. */
- /* */
- /*.............................................................*/
- void true_color_lut(void)
- {
- int i;
- unsigned char color_array[768];
- for(i=0;i<256;i++)
- {
- color_array[3*i+0]= ((i & 0x00e0) >> 5) * 9;
- color_array[3*i+1]= ((i & 0x001c) >> 2) * 9;
- color_array[3*i+2]= (i & 0x0003) * 21;
- }
- vsa_write_color_block(0,256,color_array);
- return;
- } /*..... End true_color_lut .....*/
-
- void update_message(int x0,int y0,int color,char *text)
- {
- clear_text_area(x0,y0,51,TF_Black);
- vsa_write_string(x0,y0,color,text);
- vsa_set_color(color);
- return;
- }
-
- void clear_text_area(int x0,int y0,int length,int color)
- {
- vsa_set_color(color);
- vsa_move_to(x0,y0);
- vsa_rect_fill(x0+length*XCharSize-1,y0+YCharSize-1);
- return;
- }
-
- /*.......................... VSA_GET_INPUT .................... 6-25-94 ....*/
- /* This routine reads the keyboard input and echos it to the screen until */
- /* a carriage return is entered. Then the whole text string is returned */
- /* via 'text'. */
- /*..........................................................................*/
- void vsa_get_input(char *text)
- {
- int i,x,y;
- char key;
- vsa_get_text_cursor(&x,&y);
- i=0;
- text[0] = 0;
- key = getch();
- while((key != 13) && (key != 27)) /* Do until a return */
- { /* or an ESCAPE Key is hit. */
- if(key != 8)
- { /* If not a back space */
- text[i] = key; /* add key entry to string. */
- text[i+1] = 0;
- vsa_write_string(x,y,TF_White,text);/* Echo the updated string. */
- i++;
- }
- else
- { /* If a back space */
- if(i > 0) i --; /* delete last key entry. */
- text[i] = 92;
- vsa_write_string(x,y,TF_White,text);/* Echo the updated string. */
- text[i] = 0;
- }
- key = getch();
- }
- return;
- }
-
- void color_bar(x0,y0)
- int x0,y0;
- {
- int i;
- unsigned xx,yy,a,b;
- float c;
- xx = XResolution;
- yy = YResolution;
- /*..........................................................................*/
- /* Draw outline for color bar. */
- /*..........................................................................*/
- vsa_set_color(15);
- vsa_move_to(x0-1,y0-1);
- a = .75*xx;
- b = .065*yy;
- vsa_rect(x0+a+1,y0+b+1);
- c = (float)a/256;
- for(i=0;i<256;i++)
- {
- vsa_set_color((unsigned char)i);
- vsa_move_to(x0+(unsigned)(i*c),y0);
- vsa_rect_fill(x0+(unsigned)(c+i*c),y0+b);
- }
- return;
- }
-
-